from fastapi import APIRouter, Depends, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from pydantic import BaseModel
from datetime import datetime, timedelta
import jwt
from passlib.context import CryptContext
from backend.config.database import get_db
from backend.entities.user_info import UserInfo
from backend.config.settings import settings
from backend.schemas.responses import LoginResponse, UserResponse, SuccessResponse, LoginData, UserInfo as UserInfoSchema
from backend.utils.exceptions import (
    InvalidCredentialsException,
    AuthenticationException
)

router = APIRouter(prefix="/auth", tags=["认证"])

# JWT配置
SECRET_KEY = "your-secret-key-here"  # 生产环境请使用更安全的密钥
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

security = HTTPBearer()

# bcrypt密码加密配置
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

class LoginRequest(BaseModel):
    username: str
    password: str

def create_access_token(data: dict, expires_delta: timedelta = timedelta(minutes=15)):
    """创建JWT访问令牌"""
    to_encode = data.copy()
    expire = datetime.utcnow() + (expires_delta if expires_delta else timedelta(minutes=15))
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码 - 使用bcrypt"""
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password: str) -> str:
    """获取密码哈希值 - 使用bcrypt"""
    return pwd_context.hash(password)

def authenticate_user(db: Session, username: str, password: str):
    """验证用户身份"""
    user = db.query(UserInfo).filter(UserInfo.username == username, UserInfo.status == True).first()
    if not user:
        return False
    if not verify_password(password, str(user.password_hash)):
        return False
    return user

@router.post("/login", response_model=LoginResponse)
async def login(login_data: LoginRequest, db: Session = Depends(get_db)):
    """用户登录"""
    # 验证用户身份
    user = authenticate_user(db, login_data.username, login_data.password)
    
    if not user:
        raise InvalidCredentialsException("用户名或密码错误")
    
    # 创建访问令牌
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username, "user_id": user.id, "role": user.role},
        expires_delta=access_token_expires
    )
    
    login_response_data = LoginData(
        access_token=access_token,
        token_type="bearer",
        expires_in=ACCESS_TOKEN_EXPIRE_MINUTES * 60,
        user={
            "id": user.id,
            "username": user.username,
            "role": user.role
        }
    )
    
    return SuccessResponse.create(data=login_response_data, message="登录成功")

async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db)):
    """获取当前用户信息"""
    try:
        payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise AuthenticationException("令牌无效")
    except jwt.PyJWTError:
        raise AuthenticationException("令牌验证失败")
        
    user = db.query(UserInfo).filter(UserInfo.username == username).first()
    if user is None:
        raise AuthenticationException("用户不存在")
    return user

@router.get("/me", response_model=UserResponse)
async def get_current_user_info(current_user: UserInfo = Depends(get_current_user)):
    """获取当前用户信息"""
    user_data = UserInfoSchema(
        id=int(getattr(current_user, "id", 0)),
        username=str(getattr(current_user, "username", "")),
        role=str(getattr(current_user, "role", "")),
        created_at=current_user.created_at.isoformat() if getattr(current_user, "created_at", None) is not None else None
    )

    return SuccessResponse.create(data=user_data, message="获取用户信息成功")

@router.post("/init-admin")
async def init_admin_user(db: Session = Depends(get_db)):
    """初始化管理员用户"""
    # 检查是否已存在管理员用户
    existing_admin = db.query(UserInfo).filter(UserInfo.username == "admin").first()
    if existing_admin:
        return SuccessResponse.create(
            data={"username": "admin"},
            message="管理员用户已存在"
        )
    
    # 创建默认管理员用户
    admin_user = UserInfo(
        username="admin",
        password_hash=get_password_hash("admin123"),
        role="admin",
        status=True
    )
    
    try:
        db.add(admin_user)
        db.commit()
        db.refresh(admin_user)
        
        return SuccessResponse.create(
            data={
                "username": "admin",
                "password": "admin123",
                "message": "请及时修改默认密码"
            },
            message="管理员用户创建成功"
        )
    except Exception as e:
        db.rollback()
        raise 